package org.moka.ioio.ioiopilot;


import org.moka.ioio.ioiopilot.gui.CommandPanel;
import org.moka.ioio.ioiopilot.gui.GraphSurface;

import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.IOIOFactory;
import ioio.lib.api.exception.ConnectionLostException;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

 /**
 * This is the thread that does the IOIO interaction.
 * 
 * It first creates a IOIO instance and wait for a connection to be
 * established. Then it starts doing the main work of opening the LED pin
 * and constantly updating it to match the toggle button's state.
 * 
 * Whenever a connection drops, it tries to reconnect, unless this is a
 * result of abort().
 */
public class IOIOThread extends Thread {
	public static final String TAG = "IOIOPilot";
	private IOIO ioio_;
	private boolean abort_ = false;
	private CommandPanel commandPanel;
	private GraphSurface graphPanel;
	private AbstractController pilotController;
	private Context context;

	public IOIOThread(Context context_, CommandPanel commandPanel_, GraphSurface graphPanel_)
	{ 
		commandPanel = commandPanel_;
		graphPanel = graphPanel_;
		context = context_;
	}
	
	/** Thread body. */
	@Override
	public void run() {
		super.run();
		while (true) {
			synchronized (this) {
				if (abort_) {
					break;
				}
				ioio_ = IOIOFactory.create();
			}
			try {
				pilotController = new XQuadRotorController(context, commandPanel, graphPanel);
				setText(R.string.wait_ioio);
				ioio_.waitForConnect();
				setText(R.string.ioio_connected);
				
				pilotController.initBoardIO(ioio_);

				while (true) {
					//led.write(!button_.isChecked());
					pilotController.readInputs();
					pilotController.processInputToOutput();
					pilotController.writeOutputs();
					sleep(20);
				}
			} catch (ConnectionLostException e) {
			} catch (Exception e) {
				Log.e(TAG, "Unexpected exception caught", e);
				ioio_.disconnect();
				break;
			} finally {
				try {
					ioio_.waitForDisconnect();
					setText(R.string.wait_ioio);
				} catch (InterruptedException e) {
				}
			}
		}
	}
 
	/**
	 * Abort the connection.
	 * 
	 * This is a little tricky synchronization-wise: we need to be handle
	 * the case of abortion happening before the IOIO instance is created or
	 * during its creation.
	 */
	synchronized public void abort() {
		abort_ = true;
		if (ioio_ != null) {
			ioio_.disconnect();
			setText(R.string.wait_ioio);
		}
	}

	/**
	 * Set the text line on top of the screen. 
	 * @param id The string ID of the message to present.
	 */
	private void setText(final int id) {
		commandPanel.post(new Runnable() {
			@Override
			public void run() {
				TextView title_ = (TextView)commandPanel.findViewById(R.id.title);
				title_.setText(id);
			}
		});

	}
}
